package org.imaginedays.androidall.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;

import org.imaginedays.androidall.R;
import org.imaginedays.androidall.constants.Constants;
import org.imaginedays.androidall.ui.NotifyDownloadProgressACT;
import org.imaginedays.androidall.utils.StringParaserUtils;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;

public class DownloadIntentService extends IntentService {

	private static final String TAG = DownloadIntentService.class
			.getCanonicalName();
	private NotifyHandler mHandler;
	public static final int NOTIFY_STATUE = 0;
	private NotificationManager nmgr;
	private Notification notif;
	private int notifyId = 8988;
	private int progress = 0;

	public DownloadIntentService() {
		super("DownloadIntentService");
	}

	@Override
	public void onCreate() {
		super.onCreate();
		nmgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		mHandler = new NotifyHandler();
		notifyUser("我的中国心");
	}

	@Override
	protected void onHandleIntent(Intent intent) {

		if (intent != null
				&& Constants.DOWNLOAD_APK_NOTIFICATION.equals(intent
						.getAction())) {
			final String path = intent.getStringExtra("path");
			new DownloadApkTask().execute(path);
		}
	}

	private void notifyUser(String downloadFileName) {
		notif = new Notification();
		notif.contentIntent = buildNotifyIntent();
		notif.tickerText = downloadFileName;
		notif.icon = R.drawable.ic_launcher;
		notif.contentView = buildRemoteView(downloadFileName);
	}

	class NotifyHandler extends Handler {

		public NotifyHandler(Looper looper) {
			super(looper);
		}

		public NotifyHandler() {
		}

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case NOTIFY_STATUE:
				int value = msg.arg1;
				notif.contentView.setProgressBar(R.id.pb_download_progress,
						100, value, false);
				notif.contentView.setTextViewText(R.id.tv_progress,
						String.valueOf(value) + "%");
				nmgr.notify(notifyId, notif);
				break;

			default:
				break;
			}
		}
	}

	private RemoteViews buildRemoteView(String fileName) {
		RemoteViews contentView = new RemoteViews(getPackageName(),
				R.layout.notify_download_ui);
		contentView.setImageViewResource(R.id.iv_icon, R.drawable.ic_launcher);
		contentView.setTextViewText(R.id.tv_title, fileName);
		contentView.setTextViewText(R.id.tv_progress, "0%");
		contentView.setProgressBar(R.id.pb_download_progress, 100, progress,
				false);
		return contentView;
	}

	private PendingIntent buildNotifyIntent() {
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, NotifyDownloadProgressACT.class),
				PendingIntent.FLAG_UPDATE_CURRENT);
		return contentIntent;
	}

	class DownloadApkTask extends AsyncTask<String, Integer, Void> {

		@Override
		protected Void doInBackground(String... params) {
			download(params[0]);
			return null;
		}

		@Override
		protected void onCancelled() {
			super.onCancelled();
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			notif.contentView.setTextViewText(R.id.tv_progress, "下载完成");
			nmgr.notify(notifyId, notif);
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			nmgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
			mHandler = new NotifyHandler();
			notifyUser("我的中国心");
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			notif.contentView.setProgressBar(R.id.pb_download_progress, 100,
					values[0], false);
			notif.contentView.setTextViewText(R.id.tv_progress,
					String.valueOf(values[0]) + "%");
			nmgr.notify(notifyId, notif);
		}

		public void download(String downloadUrl) {
			try {
				URL url = new URL(downloadUrl);
				HttpURLConnection urlConnection = (HttpURLConnection) url
						.openConnection();
				urlConnection.setRequestMethod("GET");
				urlConnection.setDoOutput(true);
				urlConnection.connect();

				File SDCardRoot = Environment.getExternalStorageDirectory();

				String fileName = StringParaserUtils
						.parserFileName(downloadUrl);

				File file = new File(SDCardRoot, fileName);
				FileOutputStream fileOutput = new FileOutputStream(file);

				InputStream inputStream = urlConnection.getInputStream();

				State state = new State();

				int totalSize = urlConnection.getContentLength();
				int downloadedSize = 0;
				byte[] buffer = new byte[2 * 1024];
				int bufferLength = 0;
				DecimalFormat df = new DecimalFormat("###");
				while ((bufferLength = inputStream.read(buffer)) > 0) {
					fileOutput.write(buffer, 0, bufferLength);
					downloadedSize += bufferLength;
					double size = ((double) downloadedSize / (double) totalSize) * 100;
					state.mCurrentBytes = downloadedSize;
					long now = System.currentTimeMillis();
					if (state.mCurrentBytes - state.mBytesNotified > Constants.MIN_PROGRESS_STEP
							&& now - state.mTimeLastNotification > Constants.MIN_PROGRESS_TIME) {
						Log.e(TAG, "reportProgress");
						state.mBytesNotified = state.mCurrentBytes;
						state.mTimeLastNotification = now;
						publishProgress(Integer.valueOf(df.format(size)));
					}
				}
				fileOutput.close();
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	static class State {
		public String mFilename;
		public FileOutputStream mStream;
		public String mMimeType;
		public boolean mCountRetry = false;
		public int mRetryAfter = 0;
		public int mRedirectCount = 0;
		public boolean mGotData = false;
		public long mTotalBytes = -1;
		public long mCurrentBytes = 0;
		public boolean mContinuingDownload = false;
		public long mBytesNotified = 0;
		public long mTimeLastNotification = 0;

	}

}
